#!/home/catmd5/.venv/bin/python
import hashlib
import warnings

warnings.filterwarnings(action='ignore', module='.*paramiko.*')

import json
import socket
import pandas as pd
from concurrent.futures import ThreadPoolExecutor
from cmd_line import Server

with open("./md5_config.json", 'r', encoding='utf-8') as fr:
    node_lists = json.load(fr)
md5_cmd = ''
name_list = node_lists['node_list']
results = {}
ip_range = node_lists['ip_range']
VERSION = node_lists.get('version', "None")


def test(ip):
    try:
        global md5_cmd, node_lists, results
        socket.setdefaulttimeout(5)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((ip, 22))
        s.send(bytes("INFO\r\n", 'UTF-8'))
        result = s.recv(1024).decode()

        line = Server(ip, 22, "muyi", "muyi@123")
        line.connect()
        # 使用channel发送交互指令
        line.open_channel()
        line.get_prompt(expect_symbol='$ ')
        # mes = line.channel_send_cmd('ls /mooe', '$ ').split('\n')
        mes = line.channel_send_cmd('docker ps -q --filter "name=mooe-core"', '$ ').split('\r\n')
        # if mes[1] == "ls: cannot access '/mooe': No such file or directory\r":
        # print(mes)
        if len(mes) != 4:
            robot_id = line.channel_send_cmd('cat /opt/ros/machineinfo/robot_id', '$ ')
            robot_id = robot_id.split('\r\n')[1].strip()
            # print(robot_id)
            if robot_id == "":
                return
            md5_cmd = "md5sum " + ' '.join([i['path'] for i in node_lists["node_list"]])
            # print("--------------res-----------------------")
            res = line.channel_send_cmd(md5_cmd, '$ ').split('\r\n')
            # print(res)
            md5_result = [i.split('  ') for i in res[1:-1]]
            if len(md5_result) == 0:
                return
            results[robot_id] = {}
            node_list = node_lists['node_list']
            for i in md5_result:
                if len(i) != 2:
                    continue
                for node in node_list:
                    if node['path'] == i[1]:
                        results[robot_id][node['name']] = i[0][:8]
        else:
            # mooe_core_minitor = line.channel_send_cmd('docker images | grep mooe-core-monitor', '$ ').split('\r\n')
            # mooe_core_minitor = filter(lambda x: x != '', mooe_core_minitor[1].split(' ' * 2))
            # mooe_core = line.channel_send_cmd('docker images | grep -w mooe-core | grep -v monitor', '$ ').split('\r\n')
            # mooe_core = filter(lambda x: x != '', mooe_core[1].split(' ' * 2))
            mes = line.channel_send_cmd('docker ps --filter name="mooe-core" --format "{{.Names}};{{.Image}}"',
                                        '$ ').split('\r\n')[1:3]
            line.channel_send_cmd('docker exec -it mooe-core /bin/bash', '$ ')
            robot_id = line.channel_send_cmd('cat /mooe/machineinfo/robot_id', '$ ')
            robot_id = robot_id.split('\r\n')[1].strip() + "-docker"
            if robot_id == "":
                return
            md5_cmd = "md5sum " + ' '.join([i['path'] for i in node_lists["node_list_docker"]])
            res = line.channel_send_cmd(md5_cmd, '$ ').split('\r\n')
            # print(res)
            md5_result = [i.split('  ') for i in res[1:-1]]
            if len(md5_result) == 0:
                return
            results[robot_id] = {}
            node_list = node_lists["node_list_docker"]
            for i in md5_result:
                if len(i) != 2:
                    continue
                for node in node_list:
                    if node['path'] == i[1]:
                        results[robot_id][node['name']] = i[0][:8]
            # 输出mooe-core,mooe-core-monitor的md5
            for i in range(2):
                mooe_core = mes[i].split(";")
                mooe_core_name = mooe_core[0]
                mooe_core_tag = mooe_core[1].split(":")[-1]
                mooe_core_tag_md5 = hashlib.md5(mooe_core_tag.encode('utf-8')).hexdigest()[:8]
                # mooe_core = (mooe_core_name, f'{mooe_core_tag_md5}--> {mooe_core_tag}')
                results[robot_id][mooe_core_name] = f'{mooe_core_tag_md5}-> {mooe_core_tag}'
            # results[robot_id]["mooe-core-monitor"] = list(mooe_core_minitor)[2]
            # results[robot_id]["mooe-core"] = list(mooe_core)[2]
    except:
        # print(traceback.format_exc())
        pass
    finally:
        if line:
            line.close()
            del line


if __name__ == '__main__':
    print("version: %s" % VERSION)
    pd.set_option('display.unicode.ambiguous_as_wide', True)
    pd.set_option('display.unicode.east_asian_width', True)
    # 显示所有列
    pd.set_option('display.max_columns', None)
    # 显示所有行
    pd.set_option('display.max_rows', None)
    pd.set_option('display.width', 130)
    # 设置value的显示长度为70，默认为50
    pd.set_option('max_colwidth', 70)
    # 居中对齐
    pd.set_option('display.colheader_justify', 'center')
    robot_ip = node_lists["robot_ip"]
    if len(ip_range) != 2:
        ip_range = [2, 250]
    with ThreadPoolExecutor(250) as pool:
        for i in range(ip_range[0], ip_range[1] + 1):
            ip = robot_ip + str(i)
            pool.submit(test, ip)

    if len(results) > 0:
        data = pd.DataFrame(results).T.sort_index()

        for i in name_list:
            if i['name'] in data:
                std_value = data[i['name']].value_counts().index[0]

                for robot_id in results:
                    for node_name in results[robot_id]:
                        if node_name != i['name']: continue

                        val = results[robot_id][node_name]
                        if val == std_value: continue
                        results[robot_id][node_name] = '!' + val + '!'

        data = pd.DataFrame(results).T.sort_index()
        # data.to_csv('ros_md5.csv')
        print(data, '\n')

    print('在线数量:', len(results), '\n')
